(示意圖如下:)




混淆與擴散:
混淆(Confusion):
Avalanche effect(雪崩效應):
https://cryptohack.org/courses/symmetric/aes5/
簡單介紹了混淆與擴散、雪崩效應以及ShiftRows和MixColumns的步驟。
完成inv_shift_rows後,對state執行inv_mix_columns,再進行inv_shift_rows,最後轉換為字節格式即可獲得flag。
我將程式碼分成兩部分,加密的部分題目已經給全了。
解密的部分, inv_shift_rows(s) 函式以及輸出的部份我們則要自己完善。
加密:
def shift_rows(s):
    # 執行AES的ShiftRows操作
    # 第二行左移1位
    s[0][1], s[1][1], s[2][1], s[3][1] = s[1][1], s[2][1], s[3][1], s[0][1]
    # 第三行左移2位
    s[0][2], s[1][2], s[2][2], s[3][2] = s[2][2], s[3][2], s[0][2], s[1][2]
    # 第四行左移3位
    s[0][3], s[1][3], s[2][3], s[3][3] = s[3][3], s[0][3], s[1][3], s[2][3]
# 在GF(2^8)上的乘法運算
# 如果a的最高位是1,左移後與0x1B異或;否則左移
xtime = lambda a: (((a << 1) ^ 0x1B) & 0xFF) if (a & 0x80) else (a << 1)
def mix_single_column(a):
    # 對單列進行MixColumns操作
    # 參見 The Design of Rijndael 的4.1.2節
    # 計算列中所有元素的異或和
    t = a[0] ^ a[1] ^ a[2] ^ a[3]
    u = a[0]  # 保存a[0]的原始值
    # 更新每個元素
    a[0] ^= t ^ xtime(a[0] ^ a[1])
    a[1] ^= t ^ xtime(a[1] ^ a[2])
    a[2] ^= t ^ xtime(a[2] ^ a[3])
    a[3] ^= t ^ xtime(a[3] ^ u)  # 這裡使用保存的a[0]值
def mix_columns(s):
    # 對整個狀態矩陣s執行MixColumns操作
    for i in range(4):
        mix_single_column(s[i])  # 對每一列應用mix_single_column
解密
def inv_shift_rows(s):
    # 執行AES的逆ShiftRows操作
    # 第二行右移1位
    s[1][1], s[2][1], s[3][1], s[0][1] = s[0][1], s[1][1], s[2][1], s[3][1]
    # 第三行右移2位
    s[2][2], s[3][2], s[0][2], s[1][2] = s[0][2], s[1][2], s[2][2], s[3][2] 
    # 第四行右移3位
    s[3][3], s[0][3], s[1][3], s[2][3] = s[0][3], s[1][3], s[2][3], s[3][3]
# 在GF(2^8)上的乘法運算
# 如果a的最高位是1,左移後與0x1B異或;否則左移
xtime = lambda a: (((a << 1) ^ 0x1B) & 0xFF) if (a & 0x80) else (a << 1)
    
def inv_mix_columns(s):
    # 執行AES的逆MixColumns操作
    # 參見 The Design of Rijndael 的4.1.3節
    for i in range(4):
        # 對每列進行預處理
        u = xtime(xtime(s[i][0] ^ s[i][2]))  # 計算 2 * 2 * (s[i][0] + s[i][2])
        v = xtime(xtime(s[i][1] ^ s[i][3]))  # 計算 2 * 2 * (s[i][1] + s[i][3])
        # 更新列中的每個元素
        s[i][0] ^= u
        s[i][1] ^= v
        s[i][2] ^= u
        s[i][3] ^= v
    mix_columns(s)
    
 
# 初始狀態矩陣
state = [
    [108, 106, 71, 86],
    [96, 62, 38, 72],
    [42, 184, 92, 209],
    [94, 79, 8, 54],
]
if(True):
    flag = ""
    inv_mix_columns(state)
    inv_shift_rows(state)
    # 將狀態矩陣轉換為字符串
    for i in state:
        for j in i:
           flag += chr(j)  # 將每個數值轉換為對應的ASCII字符
    print(flag)
crypto{d1ffUs3R}
wiki:
今天嘗試理解MixColumns的具體步驟,只能說,似懂非懂。